package com.mars.base.mybatis;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

import tk.mybatis.mapper.common.ConditionMapper;
import tk.mybatis.mapper.common.IdsMapper;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

import com.github.pagehelper.Page;
import com.mars.base.common.exception.BizException;
import com.mars.base.common.utils.page.PageParam;

/**
 * 继承通用Mapper，并扩展自定义接口
 * 
 * @作者：杨浩泉
 * @日期：2016年9月23日 @param <T>
 */
public interface BaseMapper<T, PK> extends Mapper<T>, MySqlMapper<T>, ConditionMapper<T>, IdsMapper<T> {

	/**
	 * <p>
	 * 保存或修改记录，<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * </p>
	 * 如下例子：
	 * 
	 * <pre>
	 * &lt;insert id="inserOrUpdate"&gt;
	 * 	&lt;selectKey keyProperty="count" resultType="int" order="BEFORE"&gt;
	 *		select count(id) from tb_user where id = #{id}
	 *	&lt;/selectKey&gt;
	 *	&lt;if test="count &gt; 0"&gt;
	 *		update tb_user
	 *		set account = #{account}
	 *		where id = #{id}
	 *	&lt;/if&gt;
	 *	&lt;if test="count==0"&gt;
	 *		insert into tb_user(id, account) values(#{id},#{account})
	 *	&lt;/if&gt;
	 * &lt;/insert&gt;
	 * </pre>
	 * 
	 * <p>
	 * 其中keyProperty是Java对象的属性名
	 * </p>
	 * 
	 * @param entity
	 *            实体对象
	 * @return int
	 */
	int inserOrUpdate(T entity);

	/**
	 * <p>
	 * 删除（根据ID 批量删除），<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * </p>
	 * 
	 * @param idList
	 *            主键ID列表
	 * @return int
	 */
	int deleteBatchIds(List<PK> idList);

	/**
	 * <p>
	 * 根据 whereEntity 条件更新记录，<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * </p>
	 * 
	 * @param entity
	 *            实体对象
	 * @return whereEntity 实体查询条件（可以为 null）
	 */
	int update(@Param("et") T entity, @Param("ew") T whereEntity);

	/**
	 * <p>
	 * 根据 whereEntity 条件选择更新记录，<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * </p>
	 * 
	 * @param entity
	 *            实体对象
	 * @return whereEntity（可以为 null） 实体查询条件
	 */
	int updateSelective(@Param("et") T entity, @Param("ew") T whereEntity);

	/**
	 * <p>
	 * 根据ID 批量更新，<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * </p>
	 * 
	 * @param entityList
	 *            实体对象列表
	 * @return int
	 */
	int updateBatchById(List<T> entityList);

	/**
	 * <p>
	 * 查询（根据ID 批量查询），<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * </p>
	 * 
	 * @param idList
	 *            主键ID列表
	 * @return List&lt;T&gt;
	 */
	List<T> selectBatchIds(List<PK> idList);

	/**
	 * <p>
	 * 查询列表，<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * </p>
	 * 
	 * @param entity
	 *            实体对象
	 * @param orderByField
	 *            排序字段
	 * @return List&lt;T&gt;
	 */
	List<T> selectList(T entity, String orderBy);

	
	/**
	 * 翻页查询，<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * @param pageParam 对象封装了分页信息和排序条件
	 * @param entity 筛选条件
	 * @return
	 */
	Page<T> selectPage(@Param("page")PageParam pageParam, @Param("entity")T entity);
	
	/**
	 * 翻页查询，<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * @param pageParam 对象封装了分页信息和排序条件
	 * @return
	 */
	Page<T> selectPage(@Param("page")PageParam pageParam);


	/**
	 * <p>
	 * 翻页查询，<b style="color:red">需要自己定义相应的Mapper标签</b>
	 * </p>
	 * 
	 * @param params
	 *            Map集合对象（检索条件）
	 * @return Page&lt;T&gt; 分页对象
	 */
	Page<T> selectPageByMap(@Param("params")Map<String, Object> params);
	
	/**
	 * 检查字段的值是否存在
	 * @param field 数据库字段
	 * @param value 值
	 * @return
	 * @throws BizException
	 */
	T checkValue(@Param("field")String field, @Param("value")Object value) ;

}
